package com.mars.admin.modules.activity.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.mars.admin.common.request.activity.ActivityRequest;
import com.mars.admin.framework.exception.BusinessException;
import com.mars.admin.framework.util.ActivityUtil;
import com.mars.admin.modules.activity.entity.Activity;
import com.mars.admin.modules.activity.entity.ActivityRegistration;
import com.mars.admin.modules.activity.mapper.ActivityMapper;
import com.mars.admin.modules.activity.mapper.ActivityRegistrationMapper;
import com.mars.admin.modules.activity.service.IActivityService;
import com.mars.admin.modules.activity.vo.ActivityVO;
import com.mars.admin.modules.goods.entity.Goods;
import com.mars.admin.modules.goods.mapper.GoodsMapper;
import com.mars.admin.modules.user.entity.User;
import com.mars.admin.modules.user.mapper.UserMapper;
import com.mars.admin.modules.user.vo.UserInfoVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mars.admin.modules.activity.entity.table.ActivityTableDef.ACTIVITY;
import static com.mars.admin.modules.activity.entity.table.ActivityRegistrationTableDef.ACTIVITY_REGISTRATION;

/**
 * 活动服务实现类
 *
 * @author Mars
 * @version 1.0
 * @date 2025-01-07
 */
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {

    @Autowired
    private ActivityRegistrationMapper activityRegistrationMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private GoodsMapper goodsMapper;

    @Override
    public Page<Activity> pageActivity(Page<Activity> page, ActivityRequest request) {

        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY).where(ACTIVITY.IS_DELETED.eq(0));

        Activity activity = BeanUtil.toBean(request, Activity.class);
        // 根据条件构建查询
        if (activity != null) {
            if (activity.getTitle() != null && !activity.getTitle().trim().isEmpty()) {
                queryWrapper.and(ACTIVITY.TITLE.like(activity.getTitle()));
            }
            if (activity.getCategoryId() != null) {
                queryWrapper.and(ACTIVITY.CATEGORY_ID.eq(activity.getCategoryId()));
            }
            if (activity.getUserId() != null) {
                queryWrapper.and(ACTIVITY.USER_ID.eq(activity.getUserId()));
            }
            if (activity.getStatus() != null) {
                queryWrapper.and(ACTIVITY.STATUS.eq(activity.getStatus()));
            }
            if (activity.getAuditStatus() != null) {
                queryWrapper.and(ACTIVITY.AUDIT_STATUS.eq(activity.getAuditStatus()));
            }
            if (activity.getActivityType() != null) {
                queryWrapper.and(ACTIVITY.ACTIVITY_TYPE.eq(activity.getActivityType()));
            }
            if (activity.getRegionId() != null) {
                queryWrapper.and(ACTIVITY.REGION_ID.eq(activity.getRegionId()));
            }
            if (activity.getIsTop() != null) {
                queryWrapper.and(ACTIVITY.IS_TOP.eq(activity.getIsTop()));
            }
            if (activity.getIsHot() != null) {
                queryWrapper.and(ACTIVITY.IS_HOT.eq(activity.getIsHot()));
            }
            if (activity.getIsRecommend() != null) {
                queryWrapper.and(ACTIVITY.IS_RECOMMEND.eq(activity.getIsRecommend()));
            }
        }

        // 按创建时间倒序排列
        queryWrapper.orderBy(ACTIVITY.CREATE_TIME.desc());

        return page(page, queryWrapper);
    }

    @Override
    public ActivityVO getActivityById(Long id) {
        Activity activity = getById(id);
        if (activity == null) {
            throw new BusinessException("活动不存在");
        }
        ActivityVO activityVO = BeanUtil.copyProperties(activity, ActivityVO.class);
        // 获取发布活动的用户信息
        User user = userMapper.selectOneById(activity.getUserId());

        activityVO.setUser(BeanUtil.copyProperties(user, UserInfoVO.class));

        if (activityVO.getGiftId() != null) {
            // 获取活动的礼品信息
            Goods goods = goodsMapper.selectOneById(activityVO.getGiftId());
            activityVO.setGift(goods);
        }
        // 计算报名人数
        // 新建List<ActivityVO>将activityVO添加到其中
        List<ActivityVO> activityVOList = new ArrayList<>();
        activityVOList.add(activityVO);

        List<ActivityVO> activityVOS = countRegistration(activityVOList);

        // 更新浏览量
        updateViewCount(id);

        // 处理登录用户的活动报名状态和支付状态
        boolean signUpStatus = false;
        Integer PaymentStatus = 0;
        ActivityVO activityVO1 = activityVOS.get(0);
        List<UserInfoVO> registrationUsers = activityVO1.getRegistrationUsers();
        for (UserInfoVO userInfoVO : registrationUsers) {
            if (userInfoVO.getId() == StpUtil.getLoginIdAsLong()){
                signUpStatus = true;
                PaymentStatus = userInfoVO.getPaymentStatus();
                break;
            }
        }

        activityVO1.setSignUpStatus(signUpStatus);
        activityVO1.setPaymentStatus(PaymentStatus);

        return activityVO1;

    }

    /**
     * 根据分类ID和状态获取活动列表
     * @param categoryId 分类ID
     * @param status     活动状态
     * @return
     */
    @Override
    public List<ActivityVO> getActivitiesByCategoryId(Long categoryId, Integer status) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY)
                .where(ACTIVITY.IS_DELETED.eq(0)).and(ACTIVITY.CATEGORY_ID.eq(categoryId));

        if (status != null) {
            queryWrapper.and(ACTIVITY.STATUS.eq(status));
        }

        queryWrapper.orderBy(ACTIVITY.CREATE_TIME.desc());

        List<Activity> activities = list(queryWrapper);

        List<ActivityVO> activityVOS = new ArrayList<>();
        if (activities != null) {
            activityVOS = BeanUtil.copyToList(activities, ActivityVO.class);

        }

        return countRegistration(activityVOS);
    }

    /**
     * 获取推荐(精选)动列表
     * @param limit 限制数量
     * @return
     */
    @Override
    public List<ActivityVO> getRecommendActivities(Integer limit) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY)
                .where(ACTIVITY.IS_DELETED.eq(0))
                .and(ACTIVITY.IS_RECOMMEND
                        .eq(1)).and(ACTIVITY.STATUS.eq(1)) // 已发布状态
                .and(ACTIVITY.AUDIT_STATUS.eq(1)) // 审核通过
                .orderBy(ACTIVITY.CREATE_TIME.desc());

        if (limit != null && limit > 0) {
            queryWrapper.limit(limit);
        }

        List<Activity> activities = list(queryWrapper);

        List<ActivityVO> activityVOList = new ArrayList<>();

        if (!activities.isEmpty()) {
            activityVOList = BeanUtil.copyToList(activities, ActivityVO.class);
        }

        return countRegistration(activityVOList);
    }

    @Override
    public List<Activity> getHotActivities(Integer limit) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY).where(ACTIVITY.IS_DELETED.eq(0)).and(ACTIVITY.IS_HOT.eq(1)).and(ACTIVITY.STATUS.eq(1)) // 已发布状态
                .and(ACTIVITY.AUDIT_STATUS.eq(1)) // 审核通过
                .orderBy(ACTIVITY.VIEW_COUNT.desc(), ACTIVITY.CREATE_TIME.desc());

        if (limit != null && limit > 0) {
            queryWrapper.limit(limit);
        }

        return list(queryWrapper);
    }

    @Override
    public List<Activity> getTopActivities(Integer limit) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY)
                .where(ACTIVITY.IS_DELETED.eq(0))
                .and(ACTIVITY.IS_TOP.eq(1))
                .and(ACTIVITY.STATUS.eq(1)) // 已发布状态
                .and(ACTIVITY.AUDIT_STATUS.eq(1)) // 审核通过
                .orderBy(ACTIVITY.CREATE_TIME.desc());

        if (limit != null && limit > 0) {
            queryWrapper.limit(limit);
        }

        return list(queryWrapper);
    }

    @Override
    public List<Activity> getActivitiesByUserId(Long userId, Integer status) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(ACTIVITY).where(ACTIVITY.IS_DELETED.eq(0)).and(ACTIVITY.USER_ID.eq(userId));

        if (status != null) {
            queryWrapper.and(ACTIVITY.STATUS.eq(status));
        }

        queryWrapper.orderBy(ACTIVITY.CREATE_TIME.desc());

        return list(queryWrapper);
    }

    @Override
    @Transactional
    public void updateViewCount(Long activityId) {
        Activity activity = getById(activityId);
        if (activity != null) {
            activity.setViewCount(activity.getViewCount() == null ? 1 : activity.getViewCount() + 1);
            updateById(activity);
        }
    }

    @Override
    @Transactional
    public void updateLikeCount(Long activityId, Integer increment) {
        Activity activity = getById(activityId);
        if (activity != null) {
            Integer currentCount = activity.getLikeCount() == null ? 0 : activity.getLikeCount();
            Integer newCount = currentCount + increment;
            activity.setLikeCount(Math.max(0, newCount)); // 确保不为负数
            updateById(activity);
        }
    }

    @Override
    @Transactional
    public void updateCommentCount(Long activityId, Integer increment) {
        Activity activity = getById(activityId);
        if (activity != null) {
            Integer currentCount = activity.getCommentCount() == null ? 0 : activity.getCommentCount();
            Integer newCount = currentCount + increment;
            activity.setCommentCount(Math.max(0, newCount)); // 确保不为负数
            updateById(activity);
        }
    }

    @Override
    @Transactional
    public void updateCollectCount(Long activityId, Integer increment) {
        Activity activity = getById(activityId);
        if (activity != null) {
            Integer currentCount = activity.getCollectCount() == null ? 0 : activity.getCollectCount();
            Integer newCount = currentCount + increment;
            activity.setCollectCount(Math.max(0, newCount)); // 确保不为负数
            updateById(activity);
        }
    }

    @Override
    @Transactional
    public void updateShareCount(Long activityId) {
        Activity activity = getById(activityId);
        if (activity != null) {
            activity.setShareCount(activity.getShareCount() == null ? 1 : activity.getShareCount() + 1);
            updateById(activity);
        }
    }

    @Override
    @Transactional
    public void auditActivity(Long activityId, Integer auditStatus, String auditReason, Long auditUserId) {
        Activity activity = getById(activityId);
        if (activity != null) {
            activity.setAuditStatus(auditStatus);
            activity.setAuditReason(auditReason);
            activity.setAuditUserId(auditUserId);
            activity.setAuditTime(LocalDateTime.now());

            // 如果审核通过，将状态设置为已发布
            if (auditStatus == 1) {
                activity.setStatus(1);
            }
            // 如果审核拒绝，将状态设置为审核拒绝
            else if (auditStatus == 2) {
                activity.setStatus(5);
            }

            updateById(activity);
        }
    }

    @Override
    @Transactional
    public boolean publish(ActivityRequest request) {
        // 参数校验
        ActivityUtil.validatePublishRequest(request);
        Activity activity = new Activity();
        BeanUtil.copyProperties(request, activity);
        activity.setImages(request.getCoverImage());
        
        // 处理images字段，确保JSON格式正确
        if (activity.getImages() == null || activity.getImages().trim().isEmpty()) {
            activity.setImages("[]"); // 设置为空数组的JSON格式
        } else {
            // 验证是否为有效的JSON格式，如果不是则包装为数组
            String images = activity.getImages().trim();
            if (!images.startsWith("[") && !images.startsWith("{")) {
                // 如果不是JSON格式，假设是单个URL，包装为数组
                activity.setImages("[\"" + images + "\"]");
            }
        }
        
        // 处理tags字段，确保JSON格式正确
        if (activity.getTags() == null || activity.getTags().trim().isEmpty()) {
            activity.setTags("[]"); // 设置为空数组的JSON格式
        } else {
            String tags = activity.getTags().trim();
            if (!tags.startsWith("[") && !tags.startsWith("{")) {
                // 如果不是JSON格式，假设是逗号分隔的字符串，转换为JSON数组
                String[] tagArray = tags.split(",");
                StringBuilder jsonTags = new StringBuilder("[");
                for (int i = 0; i < tagArray.length; i++) {
                    if (i > 0) jsonTags.append(",");
                    jsonTags.append("\"").append(tagArray[i].trim()).append("\"");
                }
                jsonTags.append("]");
                activity.setTags(jsonTags.toString());
            }
        }
        
        // 判断是新增还是更新
        if (request.getId() != null && request.getId() > 0) {
            // 更新操作
            Activity existingActivity = getById(request.getId());
            if (existingActivity == null) {
                throw new BusinessException("活动不存在");
            }
            // 保留原有的创建时间等字段
            activity.setCreateTime(existingActivity.getCreateTime());
            activity.setUpdateTime(LocalDateTime.now());
            return updateById(activity);
        } else {
            // 新增操作
            activity.setCreateTime(LocalDateTime.now());
            activity.setUpdateTime(LocalDateTime.now());
            return save(activity);
        }
    }

    @Override
    @Transactional
    public boolean deleteById(Long id) {
        Activity activity = getById(id);
        if (activity == null) {
            throw new BusinessException("活动不存在");
        }
        if (activity.getStatus() == 1) {
            throw new BusinessException("已发布的活动不允许删除");
        }
        return removeById(id);
    }

    @Override
    public long countMyActivities(Long userId) {
        return this.count(QueryWrapper.create().from(ACTIVITY).
                where(ACTIVITY.USER_ID.eq(userId)).and(ACTIVITY.IS_DELETED.eq(0)));
    }

    /**
     * 计算报名人数
     */
    public List<ActivityVO> countRegistration(List<ActivityVO> activityVOS) {
        if (activityVOS.isEmpty()) {
            return null;
        }
        // 收集活动id
        List<Long> activityIds  = activityVOS.stream()
                .map(ActivityVO::getId)
                .toList();

        // 获取有效的报名记录
        List<ActivityRegistration> activityRegistrations = activityRegistrationMapper.selectListByQuery(
                QueryWrapper.create().from(ACTIVITY_REGISTRATION)
                        .where(ACTIVITY_REGISTRATION.STATUS.eq(1))
                        .and(ACTIVITY_REGISTRATION.ACTIVITY_ID.in(activityIds))
        );
        // 根据活动id分组统计报名人数
        Map<Long, Long> registrationCountMap  = activityRegistrations.stream()
                .collect(Collectors.groupingBy(
                        ActivityRegistration::getActivityId,
                        Collectors.counting()));

        // 根据活动id分组获取报名用户列表信息
        Map<Long, List<UserInfoVO>> registrationUserMap = activityRegistrations.stream()
                .collect(Collectors.groupingBy(
                         ActivityRegistration::getActivityId,
                         Collectors.mapping(
                                 registration -> {
                                     User user = userMapper.selectOneById(registration.getUserId());
                                     UserInfoVO userInfoVO = BeanUtil.copyProperties(user, UserInfoVO.class);
                                     userInfoVO.setActivityRegistrationTime(registration.getCreateTime());
                                     userInfoVO.setPaymentStatus(registration.getPaymentStatus());

                                     return userInfoVO;
                                 },
                                 Collectors.toList()
                         )
                 ));

        // 填充报名人数和报名用户信息
        activityVOS.forEach(vo ->{
            Long count = registrationCountMap.getOrDefault(vo.getId(), 0L);
            List<UserInfoVO> userList = registrationUserMap.getOrDefault(vo.getId(), new ArrayList<>());
            vo.setRegistrationParticipants(count.intValue());
            vo.setRegistrationUsers(userList);
        });

        return activityVOS;
    }
}
